home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
Dots & Pixels
/
headers
/
vretrace.h
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-29
|
5KB
|
146 lines
#pragma once
//
// Note: instances of class 'vretrace should _never_ be allocated on a relocatable block!
// It also is unadvisory to forget to call 'stop' for an instance of vretrace for which
// 'start' has been called. If that is done the VBL routine will be called after the
// program which installed it has quit. This will sooner or later crash your machine.
//
// 950330:
//
// In article <jens_alfke-2803951102300001@jensothermac.apple.com>, jens_alfke@powertalk.apple.com (Jens Alfke) wrote:
//
// > In article <kastork-2803950428450001@slb140.cc.nps.navy.mil>,
// > kastork@nps.navy.mil (Kirk A. Stork) wrote:
// >
// > > Don't constructors have to be public?
// >
// > No. A protected or private constructor is useful, as it prevents just
// > anyone from creating an object of that class. If it's private, only a
// > method of the class can create new objects (presumably you need a public
// > static method to create the first one!). If it's protected, you can create
// > subclasses that have public constructors.
// > Similarly, you can make a class' operator new private, which prevents it
// > from being allocated on the heap.
// >
// >
// > Jens Alfke_________OpenDoc Geometer_________jens_alfke@powertalk.apple.com
// > OpenDoc info: FTP to CILabs.org
// >
// > Visit Scenic Flood Control Dam No. 3.
//
// This is something to be implemented in the future.
//
// 940204: Although the destructor does call 'stop' when needed programs using
// multiple vretrace instances do 'enter MacsBug' (some people call that 'crash')
// regularly with a message 'spurious interrupt'. I am not sure whether this is due
// to class vretrace, but calling 'stop()' for every start instance seems to prevent
// these visits to MacsBug. A hunch tells me that SC++ occasionaly optimizes out
// or forgets to call the (inline) destructor calls.
//
// BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT
//
// 950814: KNOWN BUG: the constructor vretrace::vretrace( const short how_often)
// assumes that the current graphics device belongs to a physical screen and has
// a vertical retrace queue associated with it. It uses the current graphics port
// to determine for which device the vertical retrace task should be installed.
//
// BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT BUG ALERT
//
#ifndef __CONDITIONALMACROS__
#define VBLUPP VBLProcPtr
#define NewRoutineDescriptor(theProc, theProcInfo, theISA) (theProc)
#endif
double framerate_of_main_monitor( void);
double monitor_framerate( GDHandle the_gDevice);
#pragma options align=mac68k
class vretrace
{
public:
//
// defaults: main monitor (often the only one)
//
vretrace( const short how_often = 1);
vretrace( GDHandle thegDevice, const short how_often = 1);
~vretrace();
int start(); // returns error code from SlotVInstall
int stop(); // returns error code from SlotVRemove
void set_interval( const short new_interval);
//
// reset() resets the counter and returns its old value;
//
unsigned long reset( const unsigned long new_value);
unsigned long operator()();
//
// The 'sync' members synchronise on a VBL using a busy loop.
// The integer returned is the new current value of the counter
//
unsigned long sync( const unsigned long count = 1);
void sync_till( const unsigned long count);
static short getslot( const GDHandle gDev);
private:
static VBLUPP theVBLProcPtr;
static VBLUPP allocateVBL( void);
int is_running;
//
// Note: the following three fields _must_ be kept together in
// this order (the VBL proc depends on this)
//
// 940211: Finally think I found the bug which was dormant for
// weeks (and very awake for the last week or so): numtimes_run
// should be allocated volatile since the VBL proc will change it.
// (well, it was a bug, but it apparently still was dormant)
// offset from 'myVBLTask'
short the_interval; // -0x06
volatile unsigned long numtimes_run; // -0x04
VBLTask myVBLTask; // -0x00
short mySlot;
void init( const short theSlot, const short how_often);
};
#pragma options align=reset
inline vretrace::vretrace( const short how_often)
{
init( getslot( GetGDevice()), how_often);
}
inline vretrace::vretrace( GDHandle thegDevice, const short how_often)
{
init( getslot( thegDevice), how_often);
}
inline vretrace::~vretrace()
{
if( is_running)
{
(void)stop();
}
}
inline void vretrace::set_interval( const short new_interval)
{
the_interval = new_interval;
}
inline unsigned long vretrace::operator()()
{
return numtimes_run;
}
inline double framerate_of_main_monitor( void)
{
return monitor_framerate( GetMainDevice());
}